/*
 * Copyright 2013 Agustina Martinez-Garcia

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package uk.ljmu.qudexapps.manager.utilities;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

//import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;

public class GeneralUtilities {
    private final static int BUFFER = 2048;
    private static String fileSeparator = System.getProperty("file.separator");

    public static void createFile(String fileName, InputStream input)
	    throws IOException {
	InputStream inputStream = null;
	OutputStream out = null;
	try {
	    File f = new File(fileName);
	    inputStream = input;
	    out = new FileOutputStream(f);
	    byte buf[] = new byte[1024];
	    int len;
	    while ((len = inputStream.read(buf)) > 0)
		out.write(buf, 0, len);
	    out.close();
	    inputStream.close();
	} finally {
	    if (out != null)
		out.close();
	    if (inputStream != null)
		inputStream.close();
	}
    }

    /**
     * @throws IOException
     * 
     */
    public static void copyFile(String filePath, String serverFolder)
	    throws IOException {
	InputStream outputFile = null;
	FileOutputStream out = null;
	try {
	    File inputFile = new File(filePath);
	    URL copyurl;
	    copyurl = new URL(serverFolder);
	    outputFile = copyurl.openStream();
	    out = new FileOutputStream(inputFile);
	    int c;
	    while ((c = outputFile.read()) != -1)
		out.write(c);
	    outputFile.close();
	    out.close();
	} finally {
	    if (outputFile != null)
		outputFile.close();
	    if (out != null)
		out.close();
	}
    }

    /**
     * 
     * @param serverPath
     * @param zipFile
     * @return
     * @throws IOException
     * @throws Exception
     */
    public static boolean decompressZipFile(String serverPath,
	    List<MultipartFile> zipFiles) throws IOException {
	BufferedOutputStream dest = null;
	ZipInputStream zis = null;
	try {
	    for (MultipartFile zfile : zipFiles) {
	    	if (zfile.getSize() <= Constants.FILE_MAX_MEM_SIZE) {
	    		zis = new ZipInputStream(new BufferedInputStream(zfile
	    				.getInputStream()));
	    	} else {
	    		zis = new ZipInputStream(new FileInputStream(new File(serverPath + System.getProperty("file.separator") + zfile.getOriginalFilename())));
	    	}
		ZipEntry entry;
		while ((entry = zis.getNextEntry()) != null) {
		    int count;
		    byte data[] = new byte[BUFFER];
		    // GET REAL PATH
		    String completeUrl = (serverPath.endsWith(fileSeparator)) ? serverPath
			    + entry.getName()
			    : serverPath + fileSeparator + entry.getName();

		    if (entry.isDirectory()) {
			boolean dirCreated = new File(completeUrl).mkdir();
			if (dirCreated)
			    continue;
			else
			    return false;
		    }
		    // write the files to the disk
		    FileOutputStream fos = new FileOutputStream(completeUrl);

		    dest = new BufferedOutputStream(fos, BUFFER);
		    while ((count = zis.read(data, 0, BUFFER)) != -1) {
			dest.write(data, 0, count);
		    }
		    dest.flush();
		}
	    }
	    return true;
	} finally {
	    if (dest != null)
		dest.close();
	    if (zis != null)
		zis.close();
	}
    }

    /**
     * Reverse the split operation.
     * 
     * @param parts
     *            The parts to combine
     * @param index
     *            the index to the fist part to use
     * @param length
     *            the number of parts to use
     * @param splitter
     *            The between-parts text
     */
    public static String unsplit(String[] parts, int index, int length,
	    String splitter) {
	if (parts == null)
	    return null;
	if ((index < 0) || (index >= parts.length))
	    return null;
	if (index + length > parts.length)
	    return null;

	StringBuilder buf = new StringBuilder();
	for (int i = index; i < index + length; i++) {
	    if (parts[i] != null)
		buf.append(parts[i]);
	    buf.append(splitter);
	}

	// remove the trailing splitter
	buf.setLength(buf.length() - splitter.length());
	return buf.toString();
    }

    /**
     * 
     * @param input
     * @param deleteMe
     * @return
     */
    public static List<String> removeElements(String[] input, String deleteMe) {
	List<String> result = new LinkedList<String>();
	for (String item : input)
	    if (!deleteMe.equalsIgnoreCase(item))
		result.add(item);
	return result;
    }

    static public boolean deleteDirectory(File path) {
	if (path.exists()) {
	    File[] files = path.listFiles();
	    for (int i = 0; i < files.length; i++) {
		if (files[i].isDirectory()) {
		    deleteDirectory(files[i]);
		} else {
		    files[i].delete();
		}
	    }
	}
	return (path.delete());
    }
}
